package com.pirestupppai.network;

import android.content.Context;

import com.google.gson.JsonObject;
import com.pirestupppai.adapter.PsListAdapter;
import com.pirestupppai.bean.BindStatus;
import com.pirestupppai.bean.Comment;
import com.pirestupppai.bean.DetailData;
import com.pirestupppai.bean.ErrorData;
import com.pirestupppai.bean.FeedItem;
import com.pirestupppai.bean.HomeBanner;
import com.pirestupppai.bean.LoginUser;
import com.pirestupppai.bean.MissionData;
import com.pirestupppai.bean.ShareItem;
import com.pirestupppai.bean.TagItem;
import com.pirestupppai.bean.TupaiError;
import com.pirestupppai.bean.TupaiMsg;
import com.pirestupppai.bean.TupaiUser;
import com.pirestupppai.bean.UploadFile;
import com.pirestupppai.common.Urls;
import com.pirestupppai.update.ApkBean;
import com.pirestupppai.utils.OauthUtil;
import com.trello.rxlifecycle.components.support.RxAppCompatActivity;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import static com.pirestupppai.ui.activity.FollowListActivity.FOLLOW_TYPE_FANS;

/**
 * Rx+Retrofit网络请求封装
 *
 * @author: xiaoluo
 * @date: 2017-02-28 14:31
 */
public class NetworkRequest {
    private final static String TAG = NetworkRequest.class.getSimpleName();

    private static final int DEFAULT_TIMEOUT = 15;
    private static String token = "";

    private Retrofit mRetrofit;
    private TupaiService mTupaiService;
    private static NetworkRequest mInstance;

    public static NetworkRequest getInstance() {
        token = LoginUser.TokenVerity.getToken();
        if (mInstance == null) {
            mInstance = new NetworkRequest();
        }
        return mInstance;
    }

    private NetworkRequest() {
        // 设置OkHttpClient并设置超时
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        builder.addInterceptor(new TupaiInterceptor());
        //错误重连
        builder.retryOnConnectionFailure(true);

        mRetrofit = new Retrofit.Builder()
                .client(builder.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl(Urls.BASE_URL)
                .build();

        mTupaiService = mRetrofit.create(TupaiService.class);
    }

    /**
     * observable统一转换
     */
    private void toSubscribe(Observable observable, Subscriber subscriber) {
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    /**
     * 清除配置
     */
    public void clearNetwork() {
        mInstance = null;
    }




    // ----------------------------- 所有 API 请求 ------------------------------------------

    /**
     * 版本更新
     */
    public void getVersion(Subscriber<ApkBean> subscriber) {
        Observable observable = mTupaiService.getUpdateVersionAPI()
                .map(new ResponseFunc<ApkBean>());
        toSubscribe(observable, subscriber);
    }

    /**
     * 获取用户数据
     */
    public void getUserData(int uid, Context context, Subscriber<TupaiUser> subscriber) {
        Observable observable;
        if (uid == LoginUser.getInstance().getId()) {
            observable = mTupaiService.getLoginUserDataAPI()
                    .map(new ResponseFunc<TupaiUser>())
                    .compose(((RxAppCompatActivity) context).bindToLifecycle());
        } else {
            observable = mTupaiService.getUserDataAPI(uid)
                    .map(new ResponseFunc<TupaiUser>())
                    .compose(((RxAppCompatActivity) context).bindToLifecycle());
        }

        toSubscribe(observable, subscriber);
    }

    /**
     * 校验手机号是否注册
     */
    public void checkPhone(String phone, Subscriber<JsonObject> subscriber) {
        Observable observable = mTupaiService.checkPhoneRegisterAPI(phone)
                .map(new ResponseFunc<JsonObject>());
        toSubscribe(observable, subscriber);
    }

    /**
     * 手机号登录
     */
    public void phoneLogin(String phone, String password, Subscriber<TupaiUser> subscriber) {
        Observable observable = mTupaiService.phoneLoginAPI(phone, password)
                .map(new ResponseFunc<TupaiUser>());
        toSubscribe(observable, subscriber);
    }

    /**
     * 获取验证码
     */
    public void getVerifyCode(String phone, Subscriber subscriber) {
        Observable observable = mTupaiService.getVerifyCodeAPI(phone)
                .map(new ResponseFunc());
        toSubscribe(observable, subscriber);
    }

    /**
     * 注册
     */
    public void phoneRegister(String phone, String password, String code, Subscriber<ErrorData> subscriber) {
        Observable observable = mTupaiService.phoneRegisterAPI(phone, password, code)
                .map(new ResponseFunc<ErrorData>());
        toSubscribe(observable, subscriber);
    }

    /**
     * 重置密码
     */
    public void resetPasswd(String phone, String code, String passwd, Subscriber subscriber) {
        Observable observable = mTupaiService.resetPasswdAPI(phone, code, passwd)
                .map(new ResponseFunc());
        toSubscribe(observable, subscriber);
    }

    /**
     * 获取上传token
     */
    public void getUploadToken(String filename, RxAppCompatActivity context, Subscriber<UploadFile> subscriber) {
        Observable observable = mTupaiService.getUploadTokenAPI(filename)
                .map(new ResponseFunc<UploadFile>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 上传成功后验证
     */
    public void checkUpload(int id, RxAppCompatActivity context, Subscriber<UploadFile> subscriber) {
        Observable observable = mTupaiService.checkUploadAPI(id)
                .map(new ResponseFunc<UploadFile>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * module数据
     */
    public void getModuleList(int page, int size, String type, Context context, Subscriber<List<FeedItem>> subscriber) {
        Observable observable = mTupaiService.getModulelistAPI(type, page, size)
                .map(new ResponseFunc<List<FeedItem>>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 首页标签列表
     */
    public void getHomeTagList(int page, int size, Subscriber<List<TagItem>> subscriber) {
        Observable observable = mTupaiService.getHomeTagListAPI(page, size)
                .map(new ResponseFunc<List<TagItem>>());
        toSubscribe(observable, subscriber);
    }

    /**
     * 动态列表
     */
    public void getFeedList(int page, int size, Subscriber<List<FeedItem>> subscriber) {
        Observable observable = mTupaiService.getFeedListAPI(page, size)
                .map(new ResponseFunc<List<FeedItem>>());
        toSubscribe(observable, subscriber);
    }

    /**
     * 标签求P, 作品列表
     */
    public void getTagDetailList(int id, String type, int page, int size, RxAppCompatActivity context, Subscriber<List<FeedItem>> subscriber) {
        Observable observable = mTupaiService.getTagDetailListAPI(id, type, page, size)
                .map(new ResponseFunc<List<FeedItem>>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 动态详情列表
     */
    public void getFeedDetailList(int id, int page, int size, RxAppCompatActivity context, Subscriber<DetailData> subscriber) {
        Observable observable = mTupaiService.getFeedDetailListAPI(id, page, size)
                .map(new ResponseFunc<DetailData>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 点赞一条动态
     */
    public void likeFeed(int id, Subscriber subscriber) {
        Observable observable = mTupaiService.likeFeedAPI(id)
                .map(new ResponseFunc());
        toSubscribe(observable, subscriber);
    }

    /**
     * 添加到进行中
     */
    public void createMission(int id, Subscriber subscriber) {
        Observable observable = mTupaiService.createMissionAPI(id)
                .map(new ResponseFunc());
        toSubscribe(observable, subscriber);
    }

    /**
     * 进行中列表
     */
    public void getMissionList(String type, int page, int size, Context context, Subscriber<List<MissionData>> subscriber) {
        Observable observable = mTupaiService.getMissionListAPI(type, page, size)
                .map(new ResponseFunc<List<MissionData>>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 上传作品
     * isReplyNow 为true时, 快速回复
     */
    public void uploadData(String type, String desc, List<Integer> uploadIds, List<String> tags, int parentId, int psType, Map<String, String> location,
                           RxAppCompatActivity context, Subscriber<FeedItem> subscriber) {
        Observable observable;
        if (psType == PsListAdapter.PS_TYPE_REPLY_NOW) {
            observable = mTupaiService.createReplyNowAPI(type, desc, uploadIds, tags, parentId, location)
                    .map(new ResponseFunc<FeedItem>())
                    .compose(context.bindToLifecycle());
        } else {
            observable = mTupaiService.uploadReplyDataAPI(parentId, type, desc, uploadIds, tags, location)
                    .map(new ResponseFunc<FeedItem>())
                    .compose(context.bindToLifecycle());
        }
        toSubscribe(observable, subscriber);
    }

    /**
     * 搜索标签
     */
    public void searchTag(String tag, int page, int size, Context context, Subscriber<List<TagItem>> subscriber) {
        Observable observable = mTupaiService.searchTagAPI(tag, page, size)
                .map(new ResponseFunc<List<TagItem>>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 搜索用户
     */
    public void searchUser(String user, int page, int size, Context context, Subscriber<List<TupaiUser>> subscriber) {
        Observable observable = mTupaiService.searchUserAPI(user, page, size)
                .map(new ResponseFunc<List<TupaiUser>>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 关注粉丝列表
     */
    public void getFollowList(int uid, int page, int size, int type, Context context, Subscriber<List<TupaiUser>> subscriber) {
        String listType = "followed";
        if (type == FOLLOW_TYPE_FANS) {
            listType = "follower";
        }
        Map<String, Integer> map = new HashMap<>();
        if (uid != LoginUser.getInstance().getId()) {
            map.put("target_uid", uid);
        }
        map.put("page", page);
        map.put("size", size);
        Observable observable = mTupaiService.getFollowListAPI(listType, map)
                .map(new ResponseFunc<List<TupaiUser>>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 加关注
     */
    public void createFollow(int uid, Subscriber subscriber) {
        Observable observable = mTupaiService.createFollowAPI(uid)
                .map(new ResponseFunc());
        toSubscribe(observable, subscriber);
    }

    /**
     * 取消关注
     */
    public void deleteFollow(int uid, Subscriber subscriber) {
        Observable observable = mTupaiService.deleteFollowAPI(uid)
                .map(new ResponseFunc());
        toSubscribe(observable, subscriber);
    }

    /**
     * 评论列表
     */
    public void getCommentList(int postId, int page, int size, RxAppCompatActivity context, Subscriber<List<Comment>> subscriber) {
        Observable observable = mTupaiService.getCommentListAPI(postId, page, size)
                .map(new ResponseFunc<List<Comment>>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 发送评论
     */
    public void sendComment(String content, int postId, int parentId, RxAppCompatActivity context, Subscriber<Comment> subscriber) {
        Observable observable;
        if (parentId == -1) {
            observable = mTupaiService.sendCommentAPI(content, postId, null)
                    .map(new ResponseFunc<Comment>())
                    .compose(context.bindToLifecycle());
        } else {
            observable = mTupaiService.sendCommentAPI(content, postId, parentId)
                    .map(new ResponseFunc<Comment>())
                    .compose(context.bindToLifecycle());
        }
        toSubscribe(observable, subscriber);
    }

    /**
     * 个人主页求P
     */
    public void getUserAsk(int uid, int page, int size, Context context, Subscriber<List<FeedItem>> subscriber) {
        Observable observable = mTupaiService.getAskListAPI(uid, page, size)
                .map(new ResponseFunc<List<FeedItem>>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 个人中心作品
     */
    public void getUserReply(int uid, int page, int size, Context context, Subscriber<List<FeedItem>> subscriber) {
        Observable observable = mTupaiService.getReplyListAPI(uid, page, size)
                .map(new ResponseFunc<List<FeedItem>>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 消息列表
     */
    public void getMessageList(int page, int size, RxAppCompatActivity context, Subscriber<List<TupaiMsg>> subscriber) {
        Observable observable = mTupaiService.getMessageAPI(page, size)
                .map(new ResponseFunc<List<TupaiMsg>>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 删除评论
     */
    public void deleteComment(int id, RxAppCompatActivity context, Subscriber<Comment> subscriber) {
        Observable observable = mTupaiService.deleteCommentAPI(id)
                .map(new ResponseFunc<Comment>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 删除动态
     */
    public void deleteFeed(int id, Context context, Subscriber<FeedItem> subscriber) {
        Observable observable = mTupaiService.deleteFeedAPI(id)
                .map(new ResponseFunc<FeedItem>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 修改密码
     */
    public void revisePassword(String oldPw, String newPw, RxAppCompatActivity context, Subscriber subscriber) {
        Observable observable = mTupaiService.revisePasswordAPI(oldPw, newPw)
                .map(new ResponseFunc())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 修改资料
     */
    public void reviseProfileInfo(Map<String, String> info, RxAppCompatActivity context, Subscriber<List<TupaiError>> subscriber) {
        Observable observable = mTupaiService.reviseProfileAPI(info)
                    .map(new ResponseFunc<List<TupaiError>>())
                    .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 首页Banner
     */
    public void getHomeBanner(Subscriber<List<HomeBanner>> subscriber) {
        Observable observable = mTupaiService.getHomeBannerAPI()
                .map(new ResponseFunc<List<HomeBanner>>());
        toSubscribe(observable, subscriber);
    }

    /**
     * 反馈
     */
    public void feedback(String content, RxAppCompatActivity context, Subscriber subscriber) {
        Observable observable = mTupaiService.feedbackAPI(content)
                .map(new ResponseFunc())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 举报
     */
    public void reportFeed(String type, int id, String content, Context context, Subscriber subscriber) {
        Observable observable = mTupaiService.reportAPI(type, id, content)
                .map(new ResponseFunc())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 获取分享数据
     */
    public void getShareData(int id, Context context,Subscriber<ShareItem> subscriber) {
        Observable observable = mTupaiService.getShareDataAPI(id)
                .map(new ResponseFunc<ShareItem>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 获取融云token
     */
    public void getIMtoken(RxAppCompatActivity context, Subscriber<String> subscriber) {
        Observable observable = mTupaiService.getIMtokenAPI()
                .map(new ResponseFunc<String>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 第三方登录
     */
    public void oauthLogin(Context context, String accessToken, String openId, String platform, Subscriber<TupaiUser> subscriber) {
        Observable observable = mTupaiService.oauthLoginAPI(accessToken, openId, platform)
                .map(new ResponseFunc<TupaiUser>())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 第三方绑定
     */
    public void bindThird(RxAppCompatActivity context, String accessToken, String openId, String platform, Subscriber subscriber) {
        Observable observable = mTupaiService.bindAPI(accessToken, openId, platform)
                .map(new ResponseFunc())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 解除绑定
     */
    public void deleteBind(Context context, String platform, Subscriber subscriber) {
        if (platform.equals(OauthUtil.PLATFORM_QQ)) {
            platform = "qq";
        }
        Observable observable = mTupaiService.deleteBindAPI(platform)
                .map(new ResponseFunc())
                .compose(((RxAppCompatActivity) context).bindToLifecycle());
        toSubscribe(observable, subscriber);
    }

    /**
     * 获取绑定状态
     */
    public void getBindStatus(RxAppCompatActivity context, Subscriber<BindStatus> subscriber) {
        Observable observable = mTupaiService.getBindStatusAPI()
                .map(new ResponseFunc<BindStatus>())
                .compose(context.bindToLifecycle());
        toSubscribe(observable, subscriber);
    }
}
